package cn.zzdt4j.config.service.biz.impl;

import cn.zzdt4j.common.toolkit.DateUtil;
import cn.zzdt4j.config.config.ServerBootstrapProperties;
import cn.zzdt4j.config.mapper.HisRunDataMapper;
import cn.zzdt4j.config.model.HisRunDataInfo;
import cn.zzdt4j.config.model.biz.monitor.MonitorActiveRespDTO;
import cn.zzdt4j.config.model.biz.monitor.MonitorQueryReqDTO;
import cn.zzdt4j.config.service.biz.HisRunDataService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * The type His run data service.
 *
 * @author by <a href="mailto:ligang941012@gmail.com">gang.Li</a>
 * @since 2023 /11/14 15:44
 */
@Service
@AllArgsConstructor
public class HisRunDataServiceImpl extends ServiceImpl<HisRunDataMapper, HisRunDataInfo> implements HisRunDataService {

    private final ServerBootstrapProperties properties;

    @Override
    public MonitorActiveRespDTO queryInfoThreadPoolMonitor(MonitorQueryReqDTO reqDTO) {
        Long startTime = reqDTO.getStartTime();
        Long endTime = reqDTO.getEndTime();
        if (startTime == null || endTime == null) {
            LocalDateTime currentDate = LocalDateTime.now();
            LocalDateTime dateTime = currentDate.plusMinutes(-properties.getCleanHistoryDataPeriod());
            startTime = DateUtil.getTime(dateTime);
            endTime = DateUtil.getTime(currentDate);
        }
        List<HisRunDataInfo> hisRunDataInfos = this.lambdaQuery()
                .eq(HisRunDataInfo::getTenantId, reqDTO.getTenantId())
                .eq(HisRunDataInfo::getItemId, reqDTO.getItemId())
                .eq(HisRunDataInfo::getTpId, reqDTO.getTpId())
                .eq(HisRunDataInfo::getInstanceId, reqDTO.getInstanceId())
                .between(HisRunDataInfo::getTimestamp, startTime, endTime)
                .orderByAsc(HisRunDataInfo::getTimestamp)
                .list();
        List<String> times = new ArrayList<>();
        List<Long> poolSizeList = new ArrayList<>();
        List<Long> activeSizeList = new ArrayList<>();
        List<Long> queueCapacityList = new ArrayList<>();
        List<Long> queueSizeList = new ArrayList<>();
        List<Long> rangeCompletedTaskCountList = new ArrayList<>();
        List<Long> completedTaskCountList = new ArrayList<>();
        List<Long> rangeRejectCountList = new ArrayList<>();
        List<Long> rejectCountList = new ArrayList<>();
        List<Long> queueRemainingCapacityList = new ArrayList<>();
        long completedTaskCountTemp = 0L;
        long rejectCountTemp = 0L;
        boolean firstFlag = true;
        for (HisRunDataInfo each : hisRunDataInfos) {
            String time = DateUtil.format(new Date(each.getTimestamp()), DateUtil.NORM_TIME_PATTERN);
            times.add(time);
            poolSizeList.add(each.getPoolSize());
            activeSizeList.add(each.getActiveSize());
            queueSizeList.add(each.getQueueSize());
            queueRemainingCapacityList.add(each.getQueueRemainingCapacity());
            queueCapacityList.add(each.getQueueCapacity());
            if (firstFlag) {
                firstFlag = false;
                completedTaskCountList.add(0L);
                completedTaskCountTemp = each.getCompletedTaskCount();
                rejectCountTemp = each.getRejectCount();
                continue;
            }
            rangeCompletedTaskCountList.add(each.getCompletedTaskCount() - completedTaskCountTemp);
            completedTaskCountList.add(each.getCompletedTaskCount());
            rangeRejectCountList.add(each.getRejectCount() - rejectCountTemp);
            rejectCountList.add(each.getRejectCount());
            completedTaskCountTemp = each.getCompletedTaskCount();
            rejectCountTemp = each.getRejectCount();
        }
        return MonitorActiveRespDTO.builder()
                .times(times)
                .poolSizeList(poolSizeList)
                .activeSizeList(activeSizeList)
                .queueSizeList(queueSizeList)
                .queueCapacityList(queueCapacityList)
                .rangeRejectCountList(rangeRejectCountList)
                .rejectCountList(rejectCountList)
                .completedTaskCountList(completedTaskCountList)
                .rangeCompletedTaskCountList(rangeCompletedTaskCountList)
                .queueRemainingCapacityList(queueRemainingCapacityList)
                .build();
    }
}
